package com.itistimetothink.cjetso;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicBoolean;

import com.itistimetothink.cjetso.graphics.Radar;
import com.itistimetothink.cjetso.utilities.ARData;
import com.itistimetothink.cjetso.utilities.Marker;

import android.content.Context;
import android.graphics.Canvas;
import android.util.Log;
import android.view.View;

public class AugmentedView extends View {
	private static final AtomicBoolean drawing = new AtomicBoolean(false);

	private static boolean startUsingPlus, startAside = false;
	private static final Radar radar = new Radar();
	private static final float[] locationArray = new float[3];
	private static final List<Marker> cache = new ArrayList<Marker>();
	private static final TreeSet<Marker> updated = new TreeSet<Marker>();
	private static final int VERTICAL_COLLISION_ADJUSTMENT = 10;
	private static final int HORIZONTAl_COLLISION_ADJUSTMENT = 15;

	public AugmentedView(Context context) {
		super(context);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (canvas == null)
			return;

		if (drawing.compareAndSet(false, true)) {
			List<Marker> collection = ARData.getMarkers();

			cache.clear();
			for (Marker m : collection) {
				m.update(canvas, 0, 0);
				if (m.isOnRadar())
					cache.add(m);
			}
			collection = cache;

			if (AugmentedActivity.useCollisionDetection)
				adjustForCollisions(canvas, collection);

			ListIterator<Marker> iter = collection.listIterator(collection
					.size());
			while (iter.hasPrevious()) {
				Marker marker = iter.previous();
				marker.draw(canvas);
			}
			if (AugmentedActivity.showRadar)
				radar.draw(canvas);
			drawing.set(false);
		}
	}

	private static void adjustForCollisions(Canvas canvas,
			List<Marker> collection) {
		updated.clear();

		for (Marker marker1 : collection) {
			if (updated.contains(marker1) || !marker1.isInView())
				continue;

			int collisions = 1;
			int minusCollisions = -1;
			// boolean useMinus = true;
			for (Marker marker2 : collection) {
				if (marker1.equals(marker2) || updated.contains(marker2)
						|| !marker2.isInView())
					continue;
				// TODO maybe it is suitable to add sideway adjustment
				if (marker1.isMarkerOnMarker(marker2)) {
					Log.i("Augmented View",
							"collision checking, check minusCollision = "
									+ minusCollisions);
					Log.i("Augmented View",
							"collision checking, check collision = "
									+ collisions);
					marker2.getLocation().get(locationArray);
					/*if (locationArray[1] > -160 && startUsingPlus == false
							&& startAside == false) {
						float y = locationArray[1];
						float h = minusCollisions
								* VERTICAL_COLLISION_ADJUSTMENT;
						locationArray[1] = y + h;
						marker2.getLocation().set(locationArray);
						marker2.update(canvas, 0, 0);
						Log.i("Augmented View", "collision checking -, is :"
								+ locationArray[1]);
						minusCollisions--;
						if (locationArray[1] < -160 && startUsingPlus == false) {
							startUsingPlus = true;
							Log.i("Augmented View",
									"collision checking - startUsingPlus: "
											+ locationArray[1]);
						}
					} else if (startUsingPlus == true && startAside == false) {
						float y = locationArray[1];
						float h = collisions * VERTICAL_COLLISION_ADJUSTMENT;
						locationArray[1] = y + h;
						marker2.getLocation().set(locationArray);
						marker2.update(canvas, 0, 0);
						Log.i("Augmented View", "collision checking +, is :"
								+ locationArray[1]);
						collisions++;
						if (locationArray[1] > 160 && startUsingPlus == true) {
							startUsingPlus = false;
							startAside = true;
							Log.i("Augmented View",
									"collision checking - startUsingPlus: "
											+ locationArray[1]);
						}
					} else if (startAside) {
						float x = locationArray[0];
						float h = collisions * HORIZONTAl_COLLISION_ADJUSTMENT;
						locationArray[0] = x + h;
						marker2.getLocation().set(locationArray);
						marker2.update(canvas, 0, 0);
						collisions++;
					}
					*/
					float x = locationArray[0];
					float h = collisions * HORIZONTAl_COLLISION_ADJUSTMENT;
					locationArray[0] = x + h;
					marker2.getLocation().set(locationArray);
					marker2.update(canvas, 0, 0);
					collisions++;
					updated.add(marker2);
				}
			}
			updated.add(marker1);
		}
	}
}